from django.db.models import F
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from django.utils import timezone
from django.contrib import messages
import json

from .models import Choice, Question

class IndexView(generic.ListView):
    template_name = "polls/index.html"
    context_object_name = "latest_question_list"

    def get_queryset(self):
        """Return the last five published questions."""
        questions = Question.objects.order_by("-pub_date")[:5]
        for question in questions:
            question.total_votes = sum(choice.votes for choice in question.choice_set.all())
        return questions

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        
        # 获取所有问题
        all_questions = Question.objects.all()
        
        # 计算总投票数
        total_votes = sum(
            sum(choice.votes for choice in question.choice_set.all())
            for question in all_questions
        )
        context['total_votes'] = total_votes
        
        # 获取热门投票（按总票数排序）
        hot_questions = []
        for question in all_questions:
            question.total_votes = sum(choice.votes for choice in question.choice_set.all())
            hot_questions.append(question)
        hot_questions.sort(key=lambda x: x.total_votes, reverse=True)
        context['hot_questions'] = hot_questions[:5]  # 只显示前5个热门投票
        
        # 获取最新投票
        recent_questions = Question.objects.order_by("-pub_date")[:5]
        for question in recent_questions:
            question.total_votes = sum(choice.votes for choice in question.choice_set.all())
        context['recent_questions'] = recent_questions
        
        # 添加总问题数
        context['total_questions'] = all_questions.count()
        
        return context

class DetailView(generic.DetailView):
    model = Question
    template_name = "polls/detail.html"

    def get_queryset(self):
        """
        Excludes any questions that aren't published yet.
        """
        return Question.objects.filter(pub_date__lte=timezone.now())
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        question = context['question']
        # 计算总投票数
        total_votes = sum(choice.votes for choice in question.choice_set.all())
        context['total_votes'] = total_votes
        # 添加是否已投票的状态，默认为False
        context['has_voted'] = False
        # 只有在session中存在投票记录时才设置为True
        if self.request.session.get(f'voted_{question.id}'):
            context['has_voted'] = True
            
        # 准备选项数据用于饼图
        choices_data = []
        for choice in question.choice_set.all():
            choices_data.append({
                'text': choice.choice_text,
                'votes': choice.votes
            })
        print(f"DEBUG: choices_data = {choices_data}") # 添加调试打印
        context['choices_json'] = json.dumps(choices_data, ensure_ascii=False)
        print(f"DEBUG: choices_json = {context['choices_json']}") # 添加调试打印
        
        return context

    def get(self, request, *args, **kwargs):
        # 检查是否是重新投票
        if request.GET.get('revote') == 'true':
            question = self.get_object()
            # 清除投票状态
            request.session.pop(f'voted_{question.id}', None)
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        question = self.get_object()
        try:
            selected_choice = question.choice_set.get(pk=request.POST["choice"])
        except (KeyError, Choice.DoesNotExist):
            return render(
                request,
                self.template_name,
                {
                    "question": question,
                    "error_message": "请选择一个选项。",
                    "total_votes": sum(choice.votes for choice in question.choice_set.all())
                },
            )
        else:
            selected_choice.votes = F("votes") + 1
            selected_choice.save()
            # 设置投票状态
            request.session[f'voted_{question.id}'] = True
            messages.success(request, "投票成功！")
            # 重定向到详情页，确保数据更新
            return HttpResponseRedirect(reverse('polls:detail', args=(question.id,)))

def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")

def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    choices = [{'text': choice.choice_text, 'votes': choice.votes} for choice in question.choice_set.all()]
    context = {
        'question': question,
        'choices_json': json.dumps(choices, ensure_ascii=False)
    }
    return render(request, 'polls/detail.html', context)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

from django.shortcuts import get_object_or_404, render

def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, "polls/results.html", {"question": question})

def index(request):
    latest_question_list = Question.objects.order_by("-pub_date")[:5]
    context = {"latest_question_list": latest_question_list}
    return render(request, "polls/index.html", context)

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST["choice"])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(
            request,
            "polls/detail.html",
            {
                "question": question,
                "error_message": "You didn't select a choice.",
            },
        )
    else:
        selected_choice.votes = F("votes") + 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))
    